package com.zzh.compilation.test;

class MyScanner {
    private String input;
    private int pInput;
    private char ch;
    private String token;
    private int pToken;
    private static final String[] rwtab = {"begin", "if", "then", "while", "do", "end"};

    public MyScanner(String input) {
        this.input = input;
        this.pInput = 0;
        this.token = "";
        this.pToken = 0;
    }

    private char getCh() {
        if (pInput < input.length()) {
            ch = input.charAt(pInput);
            pInput++;
        }
        return ch;
    }

    private void getBC() {
        while (ch == ' ' || ch == '\n') {
            ch = getCh();
        }
    }

    private void concat() {
        token += ch;
        pToken++;
    }

    private boolean isLetter() {
        return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
    }

    private boolean isDigit() {
        return ch >= '0' && ch <= '9';
    }

    private int reserve() {
        for (int i = 0; i < rwtab.length; i++) {
            if (token.equals(rwtab[i])) {
                return i + 1;
            }
        }
        return 10;
    }

    private void retract() {
        pInput--;
    }

    public Word scan() {
        token = "";
        pToken = 0;
        ch = getCh();
        getBC();
        if (isLetter()) {
            while (isLetter() || isDigit()) {
                concat();
                ch = getCh();
            }
            retract();
            return new Word(reserve(), token);
        } else if (isDigit()) {
            while (isDigit()) {
                concat();
                ch = getCh();
            }
            retract();
            return new Word(11, token);
        } else {
            switch (ch) {
                case '=':
                    ch = getCh();
                    if (ch == '=') {
                        return new Word(39, "==");
                    }
                    retract();
                    return new Word(25, "=");
                case '+':
                    return new Word(13, "+");
                case '-':
                    return new Word(14, "-");
                case '*':
                    return new Word(15, "*");
                case '/':
                    return new Word(16, "/");
                case '(':
                    return new Word(27, "(");
                case ')':
                    return new Word(28, ")");
                case '[':
                    return new Word(28, "[");
                case ']':
                    return new Word(29, "]");
                case '{':
                    return new Word(30, "{");
                case '}':
                    return new Word(31, "}");
                case ',':
                    return new Word(32, ",");
                case ':':
                    ch = getCh();
                    if (ch == '=') {
                        return new Word(18, ":=");
                    }
                    retract();
                    return new Word(17, ":");
                case ';':
                    return new Word(26, ";");
                case '>':
                    ch = getCh();
                    if (ch == '=') {
                        return new Word(24, ">=");
                    }
                    retract();
                    return new Word(23, ">");
                case '<':
                    ch = getCh();
                    if (ch == '=') {
                        return new Word(22, "<=");
                    } else if (ch == '>') {
                        return new Word(21, "<>");
                    }
                    retract();
                    return new Word(20, "<");
                case '!':
                    ch = getCh();
                    if (ch == '=') {
                        return new Word(40, "!=");
                    }
                    retract();
                    return new Word(-1, "ERROR");
                case '\0':
                    return new Word(1000, "OVER");
                default:
                    return new Word(0, "#");
            }
        }
    }
}